#define _CRT_SECURE_NO_WARNINGS

#include <Windows.h>
#include <stdio.h>
#include "Hw3Types.h"
#include "SyncAndProtectionModule.h"
#include "Hw3TypesExtended.h"
#include "Output.h"

// local variables declerations
HANDLE hEndFileWritten, hOutputFileWritten;
FILE *OutputFile = NULL;
FILE *EndFile = NULL;

BOOL InitializeOutputs(const char * OutputFileName, const char *EndReasonFileName) 
{
	// create the mutexes
	hEndFileWritten = CreateMutex(NULL, FALSE, NULL);
	hOutputFileWritten = CreateMutex(NULL, FALSE, NULL);
	
	// open the files
	OutputFile = fopen(OutputFileName, "w");
	EndFile = fopen(EndReasonFileName, "w");
	
	// return FALSE if any of the last actions have failed
	return !(	(hEndFileWritten == NULL) || 
				(hOutputFileWritten == NULL) ||
				(OutputFile == NULL) ||
				(EndFile == NULL));
}

void FreeOutputs()
{
	// close the handles and files
	if (!(hEndFileWritten == NULL))
		CloseHandle(hEndFileWritten);
	if (!(hOutputFileWritten == NULL))
		CloseHandle(hOutputFileWritten);
	if (!(OutputFile == NULL))
		fclose(OutputFile);
	if (!(EndFile == NULL))
		fclose(EndFile);
}

BOOL WriteOutputFile(TFace *FirstFace, TFace *SecondFace)
{
	int Res = -1;
	/* hOutputFileWritten is a mutex designed to allow only a single write to the OutputFile.
		The first matching faces found are written to the file, and the mutex is never
		realesed, until the program ends.
		This prevents other matching faces from being written to the output file. */
	if (WaitForSingleObject(hOutputFileWritten, 0) != WAIT_OBJECT_0)
		return FALSE;

	// print the face with the bigger X value on the left. this allows easier debugging and test running
	if (FirstFace->Box.OriginX > SecondFace->Box.OriginX)
		Res = fprintf(OutputFile, "(%d,%d)<->(%d,%d)", 
			FirstFace->Box.OriginY, 
			FirstFace->Box.OriginX, 
			SecondFace->Box.OriginY, 
			SecondFace->Box.OriginX);
	else
		Res = fprintf(OutputFile, "(%d,%d)<->(%d,%d)", 
			SecondFace->Box.OriginY, 
			SecondFace->Box.OriginX, 
			FirstFace->Box.OriginY, 
			FirstFace->Box.OriginX);

	// verify write was successful
	if (Res < 0)
	{
		PrintErrorAndTerminate(ERROR_WRITING_TO_FILE);
		return FALSE;
	}

	return TRUE;
}


BOOL WriteEndFile(char *EndString)
{
	/* hEndFileWritten is a mutex designed to allow only a single write to the EndFile.
		The first error created gets the mutex and never realeses it, until the program ends.
		This prevents other errors to write to the End file. */
	if (WaitForSingleObject(hEndFileWritten, 0) == WAIT_OBJECT_0)
	{
		fprintf(EndFile, "%s", EndString);
		return TRUE;
	}
	return FALSE;
}